package com.allwees.bs.c.module.order.dto;

import com.alibaba.fastjson.annotation.JSONField;
import com.allwees.bs.c.module.order.entity.CartEntity;
import com.allwees.bs.c.module.order.entity.CartItemEntity;
import com.allwees.bs.c.module.product.dto.ProductDetailsDTO;
import com.allwees.bs.c.module.product.dto.SkuDTO;
import com.allwees.bs.c.module.product.service.ProductService;
import com.allwees.core.common.util.BeanUtil;
import com.allwees.core.common.util.MoneyUtil;
import com.allwees.core.common.util.reflect.PojoUtil;
import com.allwees.support.marketing.handler.PriceAdjustor;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * @author yangylsky
 */
@Data
@Slf4j
public class CartDTO implements Serializable {

    private static final long serialVersionUID = 3913970349040521452L;

    private String uuid;

    private String userCouponUuid;

    private String userUuid;

    private String userCouponNo;

    private String userPromoLogUuid;

    private String promoCode;

    // 购物车总数量
    private Integer sum = 0;

    private BigDecimal userAmtCash = BigDecimal.ZERO;

    //展示的cash余额
    private BigDecimal showCashBalance = BigDecimal.ZERO;

    private BigDecimal amtCash = BigDecimal.ZERO;

    //订单总金额
    private BigDecimal amt = BigDecimal.ZERO;

    //订单总金额
    private BigDecimal originalAmt = BigDecimal.ZERO;

    //原始商品总价
    private BigDecimal originalAmtProduct = BigDecimal.ZERO;

    //商品总价
    private BigDecimal amtProduct = BigDecimal.ZERO;

    //运费
    private BigDecimal amtShipping = BigDecimal.ZERO;

    // 优惠商品价格
    private BigDecimal amtProductCoupon = BigDecimal.ZERO;

    //运费金额
    private BigDecimal originalAmtShipping = BigDecimal.ZERO;

    /**
     * 营业税
     */
    private BigDecimal amtSaleTax = BigDecimal.ZERO;

    /**
     * 运费险
     */
    private BigDecimal amtShippingInsurance = BigDecimal.ZERO;

    /**
     * 营业税
     */
    private boolean showSaleTax = false;

    /**
     * 运费险
     */
    private boolean showShippingInsurance = false;

    private BigDecimal deductMore = BigDecimal.ZERO;

    private BigDecimal discountRate = BigDecimal.ZERO;

    private List<CartItemDTO> items;

    @JsonIgnore
    @JSONField(serialize = false)
    private transient List<CartItemDTO> itemsWithStock;

    public CartDTO() {
    }

    public CartDTO(CartEntity entity) {
        this();
        PojoUtil.copyWithOmit(this, entity, "items");
        if (CollectionUtils.isNotEmpty(entity.getItems())) {
            items = new ArrayList<>();
            itemsWithStock = new ArrayList<>();
            for (CartItemEntity itemEntity : entity.getItems()) {
                CartItemDTO itemDto = PojoUtil.copyWithOmit(new CartItemDTO(), itemEntity, "sku", "product");
                SkuDTO sku = BeanUtil.getBean(ProductService.class).findSkuByUuid(itemEntity.getSkuUuid());
                PriceAdjustor.adjustPrice(sku);

                itemDto.setSku(sku.filter(false));
                ProductDetailsDTO productDetailsDTO = BeanUtil.getBean(ProductService.class).findProductByUuid(sku.getProductUuid());
                if (productDetailsDTO != null) {
                    itemDto.setProduct(productDetailsDTO.filter(false));
                }
                itemEntity.setProductUuid(sku.getProductUuid());

                itemDto.setOriginalAmtShipping(itemDto.getAmtShipping());
                itemDto.setAmtShipping(itemDto.getAmtShipping());
                itemDto.setProductAmtSkuAfterAdd(itemDto.amtSku());
                itemDto.setOriginalAmt(itemDto.getAmt());
                itemDto.setAmt(itemDto.amt());

                itemDto.setOriginalAmtSku(itemDto.getAmtSku());
                itemDto.setAmtSku(itemDto.getAmtSku());
                if (itemDto.getSku().getQuantity() > 0) {
                    itemsWithStock.add(itemDto);
                }
                items.add(itemDto);
            }
            this.setSum(itemsWithStock.stream().mapToInt(CartItemDTO::getQuantity).sum());
            this.setAmtProduct(amtProduct());
            this.setAmtShipping(amtShipping());
            this.setAmt(amt());
            this.setAmtCash(entity.getAmtCash());

            this.setOriginalAmt(getAmt());
            this.setOriginalAmtProduct(getAmtProduct());
            this.setOriginalAmtShipping(getAmtShipping());
        }
    }

    public BigDecimal amt() {
        return MoneyUtil.add(amtProduct(), amtShipping());
    }

    public BigDecimal amtProduct() {
        amtProduct = new BigDecimal(itemsWithStock.stream().mapToDouble(item -> item.amtSku().doubleValue()).sum()).setScale(2, BigDecimal.ROUND_HALF_UP);
        return amtProduct;
    }

    public BigDecimal amtShipping() {
        amtShipping = new BigDecimal(itemsWithStock.stream().mapToDouble(item -> item.amtShipping().doubleValue()).sum()).setScale(2, BigDecimal.ROUND_HALF_UP);
        return amtShipping;
    }
}
